﻿#ifndef CANBUS_H
#define CANBUS_H

#include <QObject>
#include <QCanBus>
#include <QCanBusDevice>
#include <QDebug>
#include <QMutexLocker>
#include <QMutex>
#include <QWaitCondition>
#include "canthread.h"

struct CanopenSDOFrame
{
    uint8_t NodeID; //站号
    uint8_t cmdWord;    //命令字
    uint16_t objectMainIndex;   //对象主索引
    uint8_t objectSubIndex; //对象子索引
    uint32_t objectIndex;
    uint32_t data {0}; //数据
    uint8_t errorCode;  //若操作失败的错误码 0x00--发送超时  0x01--发送失败 0x02--收到程序中没有预处理的报文 0x03--设置参数有误 0x80--SDO读写数据错误
    uint32_t msg;   //伺服错误代码具体错误
};

struct CanopenPDOFram
{
    uint32_t cobID;
    uint8_t data[8] = {0};
};

enum SDORECVCMDWORD{
    Recv_1byte = 0x4F,
    Recv_2byte = 0x4B,
    Recv_4byte = 0x43
};

// 定义帧类型枚举
enum class FrameType {
    SDO_REQUEST,   // SDO请求（客户端发送）
    SDO_RESPONSE,  // SDO响应（服务器发送）
    PDO,           // PDO（过程数据对象）
    OTHER          // 其他类型（如NMT、SYNC等）
};

enum CANOPENCOBID
{
    TPDO1_COBID = 0x180,
    TPDO2_COBID = 0x280,
    TPDO3_COBID = 0x380,
    RPDO1_COBID = 0x200,
    RPDO2_COBID = 0x300,
    RPDO3_COBID = 0x400,
    Heart_COBID = 0x700,
    Sync_COBID = 0x080
};

class CanOpenBus:public QObject
{
    Q_OBJECT

public:
    CanOpenBus();
    void CanbusInit();
    bool sendCanFram(quint32 framid,uint8_t *data);
    bool SDO_Read(const uint8_t& nodeid,const uint32_t& objectindex);
    bool SDO_Write(const uint8_t& nodeid, const uint32_t& objectindex, const uint8_t& count,int data);
    bool PDO_Write(uint8_t nodeid,uint32_t PDOx, uint8_t * data);
    bool MNT_Set(uint8_t nodeid,uint8_t cmd);
    bool Sync_Set();    //发送同步帧
    FrameType determineFrameType(uint32_t cob_id);
private:
    CANThread *canthread {nullptr};
private slots:
    void slot_GetProtocolData(VCI_CAN_OBJ *vci,unsigned int dwRel,unsigned int channel);
signals:
    void sig_recvPDOFrame(CanopenPDOFram frame);
    void sig_recvSDOFrame(CanopenSDOFrame frame);
};


#endif // CANBUS_H
